const bcrypt = require('bcryptjs')
const sequelize = require('sequelize/index')
const Op = sequelize.Op
const request = require("request")
/**
 * @description: 加密处理
 * @param password {原密码}
 * @param saltTimes {加盐次数}
 * @return: 加密信息
 */
const encrypt = async (password, saltTimes) => {
  const hash = await bcrypt.hashSync(password, saltTimes)
  return hash
}

/**
 * @description: 密码验证
 * @param password 原密码
 * @param hash 加密密码
 * @return:
 */
const validate = async (password, hash) => {
  const match = await bcrypt.compare(password, hash)
  return match
}
// 定义接口返回的数据模型
class BaseModel {
  constructor(data, message) {
    if (typeof data === 'string') {
      this.message = data
      data = null
      message = null
    }
    if (data) {
      this.data = data
    }

    if (message) {
      this.message = message
    }
  }
}
/**
 * @name: 成功返回模块
 * @method:
 * @msg: 成功返回模块
 * @param {type}
 */
class SuccessModel extends BaseModel {
  constructor(data, message) {
    super(data, message)
    this.code = 0
  }
}

/**
 * @name: FengWQ
 * @method:
 * @msg: 失败返回模块
 * @param {type}
 */
class ErrorModel extends BaseModel {
  constructor(data, message) {
    super(data, message)
    this.code = 1
  }
}
/**
 * @name: FengWQ
 * @method:
 * @msg: 无权限返回模块
 * @param {type}
 */
class noAuthErrorModel extends BaseModel {
  constructor(data, message) {
    super(data, message)
    this.code = 401
  }
}
const queryFilter = (params) => {
  let filter = {}
  delete params['limit']
  delete params['page']
  Object.keys(params).map((item) => {
    if (params[item]) {
      filter[item] = {
        [Op.like]: '%' + params[item] + '%',
      }
    }
  })
  return filter
}

const sonsTree = (data, id, id_name) => {
  function tree (id) {
    let arr = []
    data
      .filter((item) => {
        return item.parent_id === id
      })
      .forEach((item) => {
        const temp_item = JSON.parse(JSON.stringify(item))
        temp_item.children = tree(item[id_name])
        arr.push(temp_item)
      })
    arr.sort(function (val1, val2) {
      return val1.sort - val2.sort
    })
    return arr
  }
  return tree(id)
}
const arrayToObject = (arr) => {
  let obj = {}
  if (Array.isArray(arr)) {
    arr.map((item) => {
      obj[item.key] = [item.value]
    })
  }
  return obj
}
const generatePageUrl = (project_id, page_id) => {
  let time = parseInt(Date.now() / 1000)
  return `${time}${project_id.toString(16).toUpperCase()}PN${page_id
    .toString(16)
    .toUpperCase()}`
}
const getNodes = (links) => {
  let levelNodeIds = []
  let allNodes = []
  let root = links.filter(
    ({ target_id }) => !links.find((item) => item.source_id === target_id)
  )
  levelNodeIds = [root[0].target_id]
  allNodes.push(levelNodeIds)

  const getLevelNodeIds = (list) => {
    let ids = []
    list.forEach((item) => {
      if (levelNodeIds.includes(item.target_id)) {
        ids.push(item.source_id)
      }
    })
    if (ids.length) {
      allNodes.unshift(ids)
      levelNodeIds = ids
      getLevelNodeIds(list)
    }
  }
  getLevelNodeIds(links)
  return allNodes
}
const requestApi = function (info) {
  return new Promise(function (resolve, reject) {
    request(
      {
        url: info.server,
        method: info.methods,
        json: true,
        headers: arrayToObject(info.Headers),
        body: arrayToObject(info.Body),
        form: arrayToObject(info.Body),
      },
      function (error, response, body) {
        if (error) {
          reject(error)
        } else {
          resolve(response)
        }
      }
    )
  })
}
module.exports = {
  getNodes,
  encrypt,
  validate,
  SuccessModel,
  noAuthErrorModel,
  ErrorModel,
  queryFilter,
  sonsTree,
  arrayToObject,
  generatePageUrl,
  requestApi
}
